home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / grafik / raytracing / rayshade-4.0.6.3 / libray / libtext / imagetext.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-09  |  6.1 KB  |  242 lines

  1. /*
  2.  * imagetext.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * imagetext.c,v 4.1 1994/08/09 08:02:50 explorer Exp
  17.  *
  18.  * imagetext.c,v
  19.  * Revision 4.1  1994/08/09  08:02:50  explorer
  20.  * Bump version to 4.1
  21.  *
  22.  * Revision 1.1.1.1  1994/08/08  04:52:14  explorer
  23.  * Initial import.  This is a prerelease of 4.0.6enh3, or 4.1 possibly.
  24.  *
  25.  * Revision 4.0  91/07/17  14:42:42  kolb
  26.  * Initial version.
  27.  * 
  28.  */
  29. #include "texture.h"
  30. #include "libimage/image.h"
  31. #include "imagetext.h"
  32.  
  33. #define INTERP(v)    (text->lo + (v)*(text->hi - text->lo))
  34.  
  35. /*
  36.  * Create Image texture.
  37.  * Image texture has so many options that there's usually no
  38.  * nice way to parse without resorting to additional keywords.
  39.  * Thus the ImageTextCreate routine only reads the image to be used;
  40.  * all but ->component must be set by hand.  The routine
  41.  * ImageTextSetComponent is provided to set the component and
  42.  * ensure that the image being used is appropriate. 
  43.  */
  44. ImageText *
  45. ImageTextCreate(imagefile)
  46. char *imagefile;
  47. {
  48.     ImageText *text;
  49.  
  50.     text = (ImageText *)Calloc(1, sizeof(ImageText));
  51.     text->component = COLOR; /* texture all colors by default*/
  52.     /*
  53.      * Only apply one copy of the texture by default
  54.      */
  55.     text->tileu = text->tilev = 0;
  56.     text->lo = 0.; text->hi = 1.;
  57.     text->smooth = FALSE;
  58.     text->mapping = UVMappingCreate();
  59.     text->image = ImageRead(imagefile);
  60.     return text;
  61. }
  62.  
  63. /*
  64.  * Set image texture to apply to given component,
  65.  * ensuring that the image that is being used is compatible.
  66.  */
  67. void
  68. ImageTextSetComponent(text, component)
  69. ImageText *text;
  70. int component;
  71. {
  72.     switch (component) {
  73.     case COLOR: /* usual case, texture on amb, diff, spec, body */
  74.     case AMBIENT:
  75.     case DIFFUSE:
  76.     case SPECULAR:
  77.     case BODY:
  78.         /* all of the above can use 1 or 3 channel images */
  79.         if (text->image->chan != 1 && text->image->chan != 3) {
  80.             RLerror(RL_ABORT,
  81.                 "Image %s must have 1 or 3 channels\n", 
  82.                 text->image->filename);
  83.         }
  84.         break;
  85.     case REFLECT:
  86.     case TRANSP:
  87.     case SPECPOW:
  88.     case BUMP:
  89.     case INDEX:
  90.         /* the above need 1 channel images */
  91.         if (text->image->chan != 1) {
  92.             RLerror(RL_ABORT, "Image %s must have 1 channel\n",
  93.                 text->image->filename);
  94.         }
  95.         break;
  96.     }
  97.     text->component = component;
  98. }
  99.  
  100. void
  101. ImageTextApply(text, prim, ray, pos, norm, gnorm, surf)
  102. ImageText *text;
  103. Geom *prim;
  104. Ray *ray;
  105. Vector *pos, *norm, *gnorm;
  106. Surface *surf;
  107. {
  108.     Float fx, fy;
  109.     Float outval[4], outval_u[4], outval_v[4];
  110.     Float u, v;
  111.     Surface tmpsurf;
  112.     int ix, iy;
  113.     int rchan, gchan, bchan;
  114.     Vector dpdu, dpdv, ntmp;
  115.  
  116.     /*
  117.      * First, find the floating point location in image coords.
  118.      * Then set ix, iy to the integer location in image coords and
  119.      * use fx, fy to represent the subpixel position.
  120.      */
  121.     if (text->component == BUMP)
  122.         TextToUV(text->mapping, prim, pos, gnorm, &u, &v,
  123.              &dpdu, &dpdv);
  124.     else
  125.         TextToUV(text->mapping, prim, pos, gnorm, &u, &v, 
  126.              (Vector *)NULL, (Vector *)NULL);
  127.     /*
  128.      * Handle tiling at this point.
  129.      */
  130.     if (TileValue(text->tileu, text->tilev, u, v))
  131.         return;
  132.     u -= floor(u);
  133.     v -= floor(v);
  134.     fx = u * (Float) text->image->width;
  135.     fy = v * (Float) text->image->height;
  136.     ix = fx;
  137.     iy = fy;
  138.     fx = fx - (Float) ix;
  139.     fy = fy - (Float) iy;
  140.  
  141.     if (text->image->has_alpha) {
  142.         /* Alpha channel is 0 */
  143.         rchan = 1;
  144.         gchan = 2;
  145.         bchan = 3;
  146.     } else {
  147.         rchan = 0;
  148.         gchan = 1;
  149.         bchan = 2;
  150.     }
  151.  
  152.     if (text->image->chan == 1) {
  153.         gchan = rchan;
  154.         bchan = rchan;
  155.     }
  156.  
  157.     ImageIndex(text->image, ix, iy, fx, fy, text->smooth, outval);
  158.  
  159.     /*
  160.      * escape when alpha is zero, 'cause there is no change
  161.      */
  162.     if (text->image->has_alpha && (outval[0] < 0.001))
  163.         return;
  164.  
  165.     if (text->component != COLOR || text->surf == (Surface *)NULL) {
  166.         tmpsurf = *surf;
  167.     } else {
  168.         tmpsurf = *text->surf;
  169.     }
  170.  
  171.     switch (text->component) {
  172.         case COLOR: /* amb, diff, spec */
  173.             tmpsurf.spec.r *= outval[rchan];
  174.             tmpsurf.spec.g *= outval[gchan];
  175.             tmpsurf.spec.b *= outval[bchan];
  176.             tmpsurf.diff.r *= outval[rchan];
  177.             tmpsurf.diff.g *= outval[gchan];
  178.             tmpsurf.diff.b *= outval[bchan];
  179.             tmpsurf.amb.r *= outval[rchan];
  180.             tmpsurf.amb.g *= outval[gchan];
  181.             tmpsurf.amb.b *= outval[bchan];
  182.             break;
  183.          case AMBIENT: /* ambient */
  184.             tmpsurf.amb.r *= INTERP(outval[rchan]);
  185.             tmpsurf.amb.g *= INTERP(outval[gchan]);
  186.             tmpsurf.amb.b *= INTERP(outval[bchan]);
  187.             break;
  188.         case DIFFUSE: /* diffuse */
  189.             tmpsurf.diff.r *= INTERP(outval[rchan]);
  190.             tmpsurf.diff.g *= INTERP(outval[gchan]);
  191.             tmpsurf.diff.b *= INTERP(outval[bchan]);
  192.             break;
  193.         case SPECULAR: /* specular */
  194.             tmpsurf.spec.r *= INTERP(outval[rchan]);
  195.             tmpsurf.spec.g *= INTERP(outval[gchan]);
  196.             tmpsurf.spec.b *= INTERP(outval[bchan]);
  197.             break;
  198.         case BODY: /* transmitted */
  199.             tmpsurf.body.r *= INTERP(outval[rchan]);
  200.             tmpsurf.body.g *= INTERP(outval[gchan]);
  201.             tmpsurf.body.b *= INTERP(outval[bchan]);
  202.             break;
  203.         case REFLECT: /* specular reflectivity */
  204.             tmpsurf.reflect *= INTERP(outval[rchan]);
  205.             break;
  206.         case TRANSP: /* specular transmittance */
  207.             tmpsurf.transp *= INTERP(outval[rchan]);
  208.             break;
  209.         case SPECPOW: /* specpow */
  210.             tmpsurf.srexp *= INTERP(outval[rchan]);
  211.             break;
  212.         case INDEX: /* index of refraction */
  213.             tmpsurf.index *= INTERP(outval[rchan]);
  214.             break;
  215.         case BUMP: /* bump map */
  216.             ImageIndex(text->image, 
  217.                     (ix == text->image->width - 1) ? 0 : ix+1,
  218.                     iy, fx, fy,
  219.                     text->smooth, outval_u);
  220.             ImageIndex(text->image, ix, 
  221.                     (iy == text->image->height - 1) ? 0 : iy+1,
  222.                     fx, fy,
  223.                     text->smooth, outval_v);
  224.             MakeBump(norm, &dpdu, &dpdv, 
  225.                  INTERP(outval_u[rchan] - outval[rchan]),
  226.                  INTERP(outval_v[rchan] - outval[rchan]));
  227.             return;
  228.     }
  229.  
  230.     if (text->image->has_alpha && (outval[0] < 0.999)) {
  231.         /*
  232.          * image partial coverage means blend surf and text->surf
  233.          */
  234.         SurfaceBlend(surf, &tmpsurf, 1. - outval[0], outval[0]);
  235.     } else {
  236.         /*
  237.          * image full coverage means use text->surf
  238.          */
  239.         *surf = tmpsurf;
  240.     }
  241. }
  242.